package com.jwgf.queueprogramflash;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class FlashPageCallable implements Callable<List<Integer>> {
    private List<HexPage> hexPages;
    private List<Integer> spindles;

    public FlashPageCallable(List<HexPage> hexPages, List<Integer> spindles) {
        this.spindles = new ArrayList<>(spindles);
        this.hexPages = hexPages;
    }

    @Override
    public List<Integer> call() throws Exception {
        int pageCnt = FlashManager.getInstance().getPageCnt();
        for (int i = 0; i < pageCnt; ++i) {
            // 发送页数据
            List<byte[]> flashPageCmd = createFlashPageCmd(i);
            for (byte[] data : flashPageCmd) {
                FlashManager.getInstance().send(data);
            }
            try {
                Thread.sleep(4 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 发送查询页命令
            for (int spindle : spindles) {
                byte[] queryFlashPageCmd = FlashCommand.createQueryPageFlash(spindle);
                FlashManager.getInstance().send(queryFlashPageCmd);

            }
            try {
                Thread.sleep(4 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 获取查询烧写页结果
            List<byte[]> pageEcho = FlashManager.getInstance().getEcho();
            List<Integer> pageEchoSpindles = new ArrayList<>();
            for (byte[] echo : pageEcho) {
                int id = echo[1] & 0xff;
                if (echo[5] == 2) {
                    int pageNo = ((echo[6] & 0xff) << 8) + (echo[7] & 0xff);
                    if (pageNo == i + 1) {
                        pageEchoSpindles.add(id);
                    }
                }
            }
            //更新下次要查询的单锭
            if (pageEchoSpindles.isEmpty()) {
                return pageEchoSpindles;
            } else {
                spindles.retainAll(pageEchoSpindles);
            }
        }

        return spindles;
    }

    private List<byte[]> createFlashPageCmd(int pageNo) {
        ArrayList<byte[]> cmdList = new ArrayList<byte[]>();
        if (pageNo - 1 < hexPages.size()) {
            cmdList.add(FlashCommand.createFlashPageStart());
            byte[] data = hexPages.get(pageNo).getData();
            cmdList.add(FlashCommand.createFunctionFrame(
                    hexPages.get(pageNo).getStartAddr(), data.length,
                    pageNo + 1));
            for (int i = 0; i < data.length; i = i + 8) {
                byte[] cmd = new byte[8];
                if (i + 7 <= data.length - 1) {
                    System.arraycopy(data, i, cmd, 0, 8);
                } else {
                    System.arraycopy(data, i, cmd, 0, data.length - i);
                }
                cmdList.add(FlashCommand.createDataFrame(cmd));
            }
            cmdList.add(FlashCommand.createFlashFinish(data.length));
        }
        return cmdList;
    }
}
